#include "gwbase/base/thread.h"
#include "gwbase/base/threadlocal.h"
#include "gwbase/base/atomic.h"
#include "gwbase/base/test_harness.h"
#include <boost/bind.hpp>

class ThreadTest { };

struct Data {
  Data(): value(0) {
    s_count.Increment();
  }

  ~Data() {
    s_count.Decrement();
  }

  int value;

  static dicom::AtomicInt32 s_count;
};

dicom::AtomicInt32 Data::s_count;

static dicom::ThreadLocal<Data> g_count;

void TestThreadFunc1() 
{ 
  g_count.Set(new Data());
  g_count.Get()->value += 100;
  EXPECT_Eq(g_count.Get()->value, 100);
}

TEST(ThreadTest, Join) {
  dicom::ThreadPtr t1(new dicom::Thread(
          boost::bind(TestThreadFunc1), "t1"));
  dicom::ThreadPtr t2(new dicom::Thread(
          boost::bind(TestThreadFunc1), "t1"));

  t1->Start();
  t1->Join();

  t2->Start();
  t2->Join();

  EXPECT_Eq(g_count.Get(), static_cast<Data*>(NULL));
  EXPECT_Eq(Data::s_count.Load_Acquire(), 0);
}

int main() {
  dicom::RunAllTests();
  return 0;
}
